// 风力系统变体开关
#pragma multi_compile __ _TYPE_TREE_LEAVES _TYPE_TREE_BARK
#pragma multi_compile __ _BAKED_MESH_DATA

/*
使用说明：
1. 在你的shader中包含此文件：
   #include_with_pragmas "WindUtils.hlsl"
   注意：使用include_with_pragmas可以自动包含所有风力相关的变体开关

2. 在Properties中添加以下属性：
   Properties {
       _WindDirection ("风向", Vector) = (1,0,0,0)
       _Wind ("风速和强度", Vector) = (1,1,0,0)
       _WindStrength ("风力强度", Range(0,2)) = 1
       _WindVariation ("风力变化", Range(0,1)) = 0.3
       _TurbulenceStrength ("湍流强度", Range(0,2)) = 1
   }

3. 在CBUFFER中添加以下参数：
   CBUFFER_START(UnityPerMaterial)
       float4 _WindDirection;
       float4 _Wind;
       float _WindStrength;
       float _WindVariation;
       float _TurbulenceStrength;
       float2 _TrunkBendFactor;
       float4 g_SmoothTime;
       float4 g_PrevSmoothTime;
       float2 g_FloatingOriginOffset_Gust;
       TEXTURE2D(g_GustNoise);
       SAMPLER(sampler_g_GustNoise);
   CBUFFER_END

4. 顶点色对风力效果的影响：
   - 顶点色R通道(mask): 控制风力整体影响强度，值越大晃动越强
   - 顶点色G通道(flutter): 控制叶片边缘颤动程度，值越大边缘颤动越明显
   - 顶点色A通道(phaseOffset): 控制风力相位偏移，可用于错开不同叶片的晃动时间
   
5. 其他影响因素：
   - 顶点世界坐标高度: 越高的位置晃动幅度越大
   - 法线方向: 风力会沿着法线方向产生偏移
   - 物体轴心点: 用于计算风力变化和阵风效果，不同位置的物体会有不同的晃动节奏
   - UV1的X通道: 用于树干弯曲的mask，值越大弯曲越明显(仅适用于树干)

6. 在顶点着色器中使用：
   void vert(inout appdata_full v, out Input o) {
       UNITY_INITIALIZE_OUTPUT(Input, o);
       
       WindInput windInput;
       // 设置全局风力参数
       windInput.direction = GetWindDirection(_WindDirection);
       windInput.speed = GetWindSpeed(_Wind.x);
       
       // 设置物体级别参数
       windInput.objectPivot = mul(unity_ObjectToWorld, float4(0,0,0,1)).xyz;
       windInput.fade = 1.0;
       
       // 设置顶点级别参数
       windInput.phaseOffset = v.color.a;
       windInput.normalWS = UnityObjectToWorldNormal(v.normal);
       windInput.mask = v.color.r;
       windInput.flutter = v.color.g;
       
       float3 positionWS = mul(unity_ObjectToWorld, v.vertex).xyz;
       
       // 计算风力效果
       CalculateWind(
           positionWS,
           windInput.normalWS,
           windInput.objectPivot,
           windInput.phaseOffset,
           windInput.mask,
           windInput.flutter,
           _Time.y,
           windInput
       );
       
       // 转换回物体空间
       v.vertex = mul(unity_WorldToObject, float4(positionWS, 1.0));
   }
*/

// 风力输入结构体，包含所有风力计算所需的参数
struct WindInput
{
    // 全局参数
    float3 direction;    // 风向
    float speed;         // 风速
    
    // 物体级别参数
    float3 objectPivot;  // 物体轴心点
    float fade;          // 淡入淡出
    
    // 顶点级别参数
    float phaseOffset;   // 相位偏移
    float3 normalWS;     // 世界空间法线
    float mask;          // 风力遮罩
    float flutter;       // 颤动强度
};

// 获取全局风向
float3 GetWindDirection(float3 g_WindDirection)
{
    return g_WindDirection != 0
    ? normalize(float3(g_WindDirection.x, 0, g_WindDirection.z))
    : float3(1, 0, 0);
}

// 获取全局风速
float GetWindSpeed(float g_Wind_x)
{
    return g_Wind_x;
}

// 获取全局风力强度
float GetWindStrength(float2 g_Wind, float _WindStrength)
{
    return g_Wind.y * _WindStrength;
}

// 基于物体轴心获取随机风力变化
float GetWindVariation(float3 objectPivot, float _WindVariation)
{
    return 1.0 - frac(objectPivot.x * objectPivot.z * 10.0) * _WindVariation;
}

// 获取环境风的平滑时间偏移
float GetSmoothAmbientOffset(float timeOffset, float4 g_PrevSmoothTime, float4 g_SmoothTime)
{
    #if SHADERPASS == SHADERPASS_MOTION_VECTORS
        return timeOffset < 0 ? g_PrevSmoothTime.y : g_SmoothTime.y;
    #else
        return g_SmoothTime.y;
    #endif
}

// 获取湍流的平滑时间偏移
float GetSmoothTurbulenceOffset(float timeOffset, float4 g_PrevSmoothTime, float4 g_SmoothTime)
{
    #if SHADERPASS == SHADERPASS_MOTION_VECTORS
        return timeOffset < 0 ? g_PrevSmoothTime.z : g_SmoothTime.z;
    #else
        return g_SmoothTime.z;
    #endif
}

// 获取全局湍流强度
float GetTurbulenceStrength(float2 g_Turbulence, float _TurbulenceStrength)
{
    return g_Turbulence.y * _TurbulenceStrength;
}

// 计算环境风频率（使用正弦波模拟周期性运动）
float4 AmbientFrequency(
    float3 objectPivot,         // 物体轴心
    float3 vertexWorldPosition, // 顶点世界坐标
    float3 windDirection,       // 风向
    float phaseOffset,         // 相位偏移
    float scale,               // 缩放系数
    float time)                // 时间
{
    float4 sine;
    float frequency = time * scale;
    sine.x = sin(frequency + objectPivot.x * 0.5);
    sine.z = sin(frequency * 0.8 + objectPivot.z * 0.5);
    sine.y = sin(frequency * 0.7 + objectPivot.y * 0.5);
    sine.w = sin(frequency * 0.5 + phaseOffset);
    return sine;
}

// 计算环境风（基础的周期性摆动）
float3 AmbientWind(
    float3 objectPivot,         // 物体轴心
    float3 vertexWorldPosition, // 顶点世界坐标
    float3 windDirection,       // 风向
    float phaseOffset,         // 相位偏移
    float time)                // 时间
{
    float4 sine = AmbientFrequency(objectPivot, vertexWorldPosition, windDirection, phaseOffset, 1, time);
    sine.w = abs(sine.w) + 0.5;
    float xz = 1.5 * sine.x * sine.z + sine.w + 1;
    float y = 1 * sine.y * sine.z + sine.w;
    return windDirection * float3(xz, 0, xz) + float3(0, y, 0);
}

// 从噪声纹理采样阵风效果（随机的风力突变）
float3 SampleGust(
    float3 objectPivot,         // 物体轴心
    float3 vertexWorldPosition, // 顶点世界坐标
    float3 windDirection,       // 风向
    float phaseOffset,         // 相位偏移
    float edgeFlutter,         // 边缘颤动
    float lod,                 // 细节层级
    float2 windOffset,         // 风力偏移
    float2 g_FloatingOriginOffset_Gust, // 浮动原点偏移
    sampler2D g_GustNoise)     // 阵风噪声纹理
{
    #if defined(_TYPE_TREE_LEAVES) || defined(_TYPE_TREE_BARK)
        windOffset -= phaseOffset.xx * 0.05;
        lod = 5;
    #else
        windOffset -= phaseOffset.xx * 0.05;
    #endif
    
    #if defined(_TYPE_TREE_LEAVES)
        float3 vertexOffset = vertexWorldPosition - objectPivot;
        float2 offset = (objectPivot.xz + g_FloatingOriginOffset_Gust) * 0.02 - windOffset.xy + vertexOffset.xz * 0.0075 * edgeFlutter;
    #else
        float2 offset = (objectPivot.xz + g_FloatingOriginOffset_Gust) * 0.02 - windOffset.xy;
    #endif
    float strength = tex2Dlod(g_GustNoise, float4(offset, 0, lod)).r;
    return strength * windDirection;
}

// 组合不同风力组件
float3 CombineWind(
    float3 ambient,    // 环境风
    float3 gust,       // 阵风
    float3 turbulence, // 湍流
    float3 shiver,     // 颤抖
    float4 strength)   // 各组件强度
{
    return ambient * strength.x 
         + gust * strength.y 
         + turbulence * strength.z
         + shiver * strength.w;
}

// 将风力应用到顶点位置
float3 ApplyWind(
    float3 positionWS,    // 世界空间顶点位置
    float3 objectPivot,   // 物体轴心
    float3 combinedWind,  // 组合后的风力
    float mask,           // 风力遮罩
    float distanceFade)   // 距离衰减
{
    float3 wind = combinedWind * mask * distanceFade;
    return positionWS + wind;
}

// 主要的风力计算函数
void CalculateWind(
    inout float3 positionWS, // 世界空间顶点位置
    float3 normalWS,         // 世界空间法线
    float3 objectPivot,      // 物体轴心
    float phaseOffset,       // 相位偏移
    float mask,              // 风力遮罩
    float flutter,           // 颤动强度
    float timeOffset,        // 时间偏移
    WindInput input)         // 风力输入参数
{
    // 计算环境风
    float3 ambient = AmbientWind(
        input.objectPivot,
        positionWS,
        input.direction,
        input.phaseOffset,
        timeOffset);

    // 计算阵风
    float2 windOffset = float2(timeOffset * 0.5, timeOffset);
    float3 gust = SampleGust(
        input.objectPivot,
        positionWS,
        input.direction,
        input.phaseOffset,
        input.flutter,
        1,
        windOffset,
        float2(0,0), // 替换为实际的 g_FloatingOriginOffset_Gust
        g_GustNoise); // 替换为实际的 g_GustNoise 纹理

    // 计算湍流（这里可以添加自定义的湍流计算）
    float3 turbulence1 = float3(0,0,0);
    float3 turbulence2 = float3(0,0,0);

    // 组合所有风力效果
    float3 combinedWind = CombineWind(
        ambient,
        gust,
        turbulence1,
        turbulence2,
        float4(input.speed, input.speed, 1.0, 1.0));

    // 应用风力到顶点位置
    positionWS = ApplyWind(
        positionWS,
        objectPivot,
        combinedWind,
        mask,
        1.0); // 替换为实际的距离衰减计算
}

// 树干弯曲相关函数
float2 GetTrunkBendFactor(float2 _TrunkBendFactor)
{
    return _TrunkBendFactor.xy;
}

float GetTrunkMask(
    float3 vertex,
    float2 uv1,
    float treeHeight,
    float bendFactor,
    float baseBendFactor)
{
    #ifdef _BAKED_MESH_DATA
        float trunkMask = saturate(uv1.x * bendFactor);
    #else
        float trunkMask = pow2(saturate(vertex.y / treeHeight)) * bendFactor;
    #endif
    
    return saturate(trunkMask + saturate(vertex.y) * baseBendFactor);
}

// 旋转函数
float3 RotateAroundAxis(
    float3 center,
    float3 original,
    float3 axis,
    float angle)
{
    float3 rotated = original - center;
    float c = cos(angle);
    float s = sin(angle);
    float t = 1 - c;
    
    float3x3 rotationMatrix = float3x3(
        t * axis.x * axis.x + c, t * axis.x * axis.y - s * axis.z, t * axis.x * axis.z + s * axis.y,
        t * axis.x * axis.y + s * axis.z, t * axis.y * axis.y + c, t * axis.y * axis.z - s * axis.x,
        t * axis.x * axis.z - s * axis.y, t * axis.y * axis.z + s * axis.x, t * axis.z * axis.z + c
    );
    
    rotated = mul(rotationMatrix, rotated);
    rotated += center;
    
    return rotated;
}

// 树干风力计算
void Wind_Trunk(
    float3 vertex,                // 物体空间顶点位置
    float3 vertexWorldPosition,   // 世界空间顶点位置
    float3 vertexWithWind,       // 带风力效果的世界空间顶点位置
    float2 uv1,                  // 第二UV通道
    float3 objectPivot,          // 世界空间物体轴心
    float3 windDirection,        // 世界空间风向
    float timeOffset,            // 时间偏移
    out float3 vertexOut)        // 输出的顶点位置
{
    // 获取额外属性
    float2 bendFactor = GetTrunkBendFactor(_TrunkBendFactor);
    float trunkMask = GetTrunkMask(vertex, uv1, GetObjectHeight(), bendFactor.x, bendFactor.y);
    float ambientStrength = GetWindStrength(g_Wind, _WindStrength);
    
    // 计算环境风
    float4 trunkAmbient =
        AmbientFrequency(
            objectPivot,
            vertexWorldPosition,
            windDirection,
            0,
            0.75,
            timeOffset) + ambientStrength;
    trunkAmbient *= trunkMask;
    
    // 计算阵风
    float3 trunkGust =
        SampleGust(
            objectPivot,
            vertexWorldPosition,
            windDirection,
            0,
            0,
            7,
            float2(timeOffset * 0.5, timeOffset),
            g_FloatingOriginOffset_Gust,
            g_GustNoise);
    trunkGust *= trunkMask;
    
    // 应用风力效果
    float gustFrequency = trunkAmbient.w * length(trunkGust);
    float baseFrequency1 = trunkAmbient.x;
    float baseFrequency2 = trunkAmbient.x + trunkAmbient.y;
    float baseFrequency =
        lerp(baseFrequency1, baseFrequency2, (_SinTime.x + 1) * 0.5 * ambientStrength);
    
    vertexOut =
        RotateAroundAxis(
            objectPivot,
            vertexWithWind,
            normalize(cross(float3(0,1,0), windDirection)),
            (baseFrequency * 0.75 + gustFrequency) * ambientStrength * 0.0375);
}

// 修复拉伸问题的函数
float3 FixStretching(float3 positionWS, float3 originalPositionWS, float3 pivot)
{
    float3 offset = positionWS - pivot;
    float3 originalOffset = originalPositionWS - pivot;
    return pivot + normalize(offset) * length(originalOffset);
} 